package com.sh.data.engine.domain.api.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sh.data.engine.common.enumDefinition.DataApiApproveStatusEnum;
import com.sh.data.engine.common.enumDefinition.DataApiStatusEnum;
import com.sh.data.engine.common.exception.BusinessException;
import com.sh.data.engine.domain.api.model.domain.DataApiAuthDomain;
import com.sh.data.engine.domain.api.model.domain.DataApiSecurityManageDomain;
import com.sh.data.engine.domain.api.service.*;
import com.sh.data.engine.domain.authority.service.TokenService;
import com.sh.data.engine.domain.util.ConvertUtil;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserDomain;
import com.sh.data.engine.domain.workspace.manager.service.UserService;
import com.sh.data.engine.repository.dao.api.entity.DataApiAuthEntity;
import com.sh.data.engine.repository.dao.api.entity.DataApiEntity;
import com.sh.data.engine.repository.dao.api.entity.DataApiUserStatisticsEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author : fuchen
 * @date : 2022/2/10 18:30
 */
@Service
public class DataApiSecurityManageServiceImpl implements DataApiSecurityManageService {

    private static final String API_REDIS_KEY_PREFIX = "data_api_";

    @Autowired
    private DataApiAuthService dataApiAuthService;

    @Autowired
    private DataApiService dataApiService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private DataApiUserStatisticsService dataApiUserStatisticsService;

    @Autowired
    private DataApiRestService dataApiRestService;

    @Autowired
    private TokenService tokenService;

    @Override
    public IPage<DataApiSecurityManageDomain> getApiSecurityManagePage(
        String apiName, Long projectId, Integer pageNum, Integer pageSize) {

        LambdaQueryWrapper<DataApiEntity> eq =
            new LambdaQueryWrapper<DataApiEntity>().eq(DataApiEntity::getProjectId, projectId);

        if (StringUtils.isNotBlank(apiName)) {
            eq.like(DataApiEntity::getApiName, apiName);
        }

        IPage<DataApiSecurityManageDomain> convert =
            dataApiService
                .page(new Page<>(pageNum, pageSize), eq)
                .convert(e -> Convert.convert(DataApiSecurityManageDomain.class, e));
        List<DataApiSecurityManageDomain> result = convert.getRecords();

        for (DataApiSecurityManageDomain dataApiSecurityManageDomain : result) {
            Long id = dataApiSecurityManageDomain.getId();
            LambdaQueryWrapper<DataApiAuthEntity> eq1 =
                new LambdaQueryWrapper<DataApiAuthEntity>()
                    .eq(DataApiAuthEntity::getApiId, id)
                    .eq(DataApiAuthEntity::getApproveStatus, DataApiStatusEnum.PUBLISHED.getStatus());

            long count = dataApiAuthService.count(eq1);
            dataApiSecurityManageDomain.setUserNumber(count);
        }

        return convert;
    }

    @Override
    public IPage<DataApiSecurityManageDomain> getApiSecurityManagePage(
        Long projectId, Long apiId, String searchName, Integer pageNum, Integer pageSize) {
        DataApiEntity dataApiEntity = dataApiService.getById(apiId);
        if (null == dataApiEntity) {
            throw new BusinessException("该API不存在或者未发布,无法审核");
        }

        LambdaQueryWrapper<DataApiAuthEntity> eq =
            new LambdaQueryWrapper<DataApiAuthEntity>()
                .eq(DataApiAuthEntity::getProjectId, projectId)
                .eq(DataApiAuthEntity::getApiId, apiId)
                .eq(
                    DataApiAuthEntity::getApproveStatus,
                    DataApiApproveStatusEnum.PASSED.getApproveStatus());
        if (StringUtils.isNotBlank(searchName)) {
            eq.like(DataApiAuthEntity::getUsername, searchName);
        }

        IPage<DataApiSecurityManageDomain> convert =
            dataApiAuthService
                .page(new Page<>(pageNum, pageSize), eq)
                .convert(e -> Convert.convert(DataApiSecurityManageDomain.class, e));

        List<DataApiSecurityManageDomain> result = convert.getRecords();
        for (DataApiSecurityManageDomain manageDomain : result) {

            DataApiUserStatisticsEntity one =
                dataApiUserStatisticsService.getOne(
                    new LambdaQueryWrapper<DataApiUserStatisticsEntity>()
                        .eq(DataApiUserStatisticsEntity::getApiId, apiId)
                        .eq(DataApiUserStatisticsEntity::getUsername, manageDomain.getUsername()));

            manageDomain.setTotalCount(one == null ? 0 : one.getTotalCount());
            manageDomain.setApiId(apiId);
            if (manageDomain.getTotalCount() == null) {
                manageDomain.setTotalCount(0L);
            }
        }
        return convert;
    }

    @Override
    public Boolean cancelApiSecurityManageById(Long projectId, String userId, Long apiId) {
        DataApiAuthDomain dataApiAuthDomain =
            dataApiAuthService.findAuthDomainByUserIdAndApiId(userId, apiId);

        DataApiEntity dataApiEntity = dataApiService.getById(dataApiAuthDomain.getApiId());
        if (null == dataApiAuthDomain) {
            throw new BusinessException("此申请无法被处理");
        }
        dataApiAuthDomain.setApproveStatus(DataApiApproveStatusEnum.CANCELD.getApproveStatus());
        String key =
            new StringBuilder(API_REDIS_KEY_PREFIX)
                .append("token")
                .append("_")
                .append(dataApiAuthDomain.getApiToken())
                .toString();
        redisTemplate.delete(key);

        UserDomain userById = userService.getUserById(userId);
        String key2 =
            API_REDIS_KEY_PREFIX + "token" + "_" + tokenService.getToken(userById.getId()) + dataApiEntity.getApiPath();
        redisTemplate.delete(key2);

        dataApiRestService.removeConfigCache(dataApiEntity.getId(), dataApiEntity.getApiPath());
        DataApiAuthEntity dataApiAuthEntity =
            ConvertUtil.copyProperties(dataApiAuthDomain, DataApiAuthEntity.class);
        dataApiAuthService.updateById(dataApiAuthEntity);
//        LogContext.put(LogKey.NAME.getKey(), dataApiAuthEntity.getApiName());
        return true;
    }
}
